﻿using Furion.DynamicApiController;
using Furion.Templates.Extensions;
using Furion.ViewEngine;
using Furion.ViewEngine.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Application
{
    /// <summary>
    /// 视图引擎服务
    /// </summary>
    public class ViewEngineService : IDynamicApiController
    {
        private readonly IViewEngine _viewEngine;

        public ViewEngineService(IViewEngine viewEngine)
        {
            _viewEngine = viewEngine;
            var result = _viewEngine.RunCompile("Hello @Model.Name", new { Name = "Furion" });

            // 字符串方式
            var strResult = "Hello @Model.Name".RunCompile(new { Name = "Furion" });

            // 弱类型模板
            var weakTypeTemplateResult = _viewEngine.RunCompile("Hello @Model.Name", new { Name = "Furion" });

            // 强类型模板
            var stronglyTypedTemplateResult = _viewEngine.RunCompile(@"
                Hello @Model.Name
                @foreach(var item in Model.Items)
                {
                    <p>@item</p>
                }
                ", new TestModel
                {
                    Name = "Furion",
                    Items = new[] { 3, 1, 2 }
                });

            // 调用RunCompileFromCached方法之后将会使用MD5加密模板并生成MD5字符串的.dll存放在网站根目录下的templates目录中。只要模板内容不变，数据发生改变也不会重新编译模板
            var runCompileFromCachedResult = _viewEngine.RunCompileFromCached(@"
                Hello @Model.Name
                @foreach(var item in Model.Items)
                {
                    <p>@item</p>
                }
                ", new TestModel
                {
                    Name = "Furion",
                    Items = new[] { 5, 6, 7, 8 }
                });

            #region 高级用法

            // 添加程序集
            var ioResult = _viewEngine.RunCompileFromCached(@"<div>@System.IO.Path.Combine(""Furion"", ""ViewEngine"")</div>", builderAction: builder =>
            {
                builder.AddAssemblyReferenceByName("System.IO");
                
                // 另外，Furion提供多种方式加载程序集
                builder.AddAssemblyReferenceByName("System.Security"); // 通过名称
                builder.AddAssemblyReference(typeof(System.IO.File)); // 通过类型
                builder.AddAssemblyReference(Assembly.Load("source")); // 通过元数据引用
            });

            // 添加命名空间
            var pathResult = _viewEngine.RunCompileFromCached(@"<div>@Path.Combine(""Furion"", ""ViewEngine"")</div>", builderAction: builder =>
            {
                builder.AddUsing("System.IO");
                // 也支持加入多个using：
                builder.AddUsing("Furion");
                builder.AddAssemblyReferenceByName("System.IO");
            });

            // 定义模板方法
            var recursionResult = _viewEngine.RunCompileFromCached(@"
                <area>
                    @{ RecursionTest(3); }
                </area>

                @{
                  void RecursionTest(int level)
                  {
                    if (level <= 0)
                    {
                        return;
                    }

                    <div>LEVEL: @level</div>
                    @{ RecursionTest(level - 1); }
                  }
                }
                ");

            // 调用类方法
            var content = @"Hello @A, @B, @Decorator(123)";

            var template = _viewEngine.Compile<CustomModel>(content);

            var templateResult = template.Run(instance =>
            {
                instance.A = 10;
                instance.B = "Alex";
            });

            #endregion

            #region 字符串模板替换引擎

            //// 提供数据模板方式
            //var str = "我叫{name}".Render(new Dictionary { { "name", "Furion" } });
            //var str1 = "我叫{Name}".Render(new { Name = "Furion" });
            //var str2 = "我叫{Detail.Name}".Render(new { Detail = new { Name = "Furoin" } });

            //// 从配置读取方式
            //var str3 = "我叫#(Furion:Address)".Render();

            // appsettings.json配置
            //{
            //    "Furion": {
            //        "Address": "https://www.furion.pro"
            //    }
            //}

            #endregion
        }
    }
}
